/**
 * This file is Copyright © 2008 Software Craftsmen Limited. All Rights Reserved.
 */
package com.softwarecraftsmen.orogeny.actions;

import com.softwarecraftsmen.orogeny.buildEnvironments.BuildEnvironment;
import com.softwarecraftsmen.orogeny.buildLogs.BuildLog;
import com.softwarecraftsmen.orogeny.buildLogs.Verbosity;
import com.softwarecraftsmen.orogeny.execution.SuccessOrFailure;
import static com.softwarecraftsmen.orogeny.execution.SuccessOrFailure.Success;
import static com.softwarecraftsmen.orogeny.filing.AbsoluteDirectoriesAndFiles.absoluteDirectoriesAndFiles;
import com.softwarecraftsmen.orogeny.filing.AbsoluteDirectory;
import com.softwarecraftsmen.orogeny.filing.AbsolutePath;
import org.jetbrains.annotations.NotNull;

import static java.lang.String.format;
import static java.util.Locale.UK;

public class ClassExistsAction extends AbstractAction
{
	private final String className;
	private final AbsoluteDirectory directory;

	public ClassExistsAction(final @NotNull String className, final @NotNull AbsoluteDirectory directory)
	{
		this.className = className;
		this.directory = directory;
	}

	@NotNull
	public String describeWhatWeDo()
	{
		return "classExists";
	}

	@NotNull
	public SuccessOrFailure execute(final @NotNull BuildLog buildLog, final @NotNull BuildEnvironment buildEnvironment)
	{
		buildLog.writeMessage(Verbosity.Summary, format(UK, "About to check class %1$s exists in %2$s", className, directory));

		final String[] parts = className.replace("/", ".").split(".");
		AbsoluteDirectory currentDirectory = directory;
		for (int index = 0; index < parts.length - 1; index++)
		{
			final SuccessOrFailure status = folderExists(buildLog, buildEnvironment, currentDirectory.subDirectory(parts[index]));
			if (status.isFailure())
			{
				return status;
			}
		}
		if (parts.length > 0)
		{
			final SuccessOrFailure status = folderExists(buildLog, buildEnvironment, currentDirectory.file(parts[parts.length - 1] + ".class"));
			if (status.isFailure())
			{
				return status;
			}
		}
		return Success;
	}

	private SuccessOrFailure folderExists(final BuildLog buildLog, final BuildEnvironment buildEnvironment, final AbsolutePath path)
	{
		return new ExistsAction(absoluteDirectoriesAndFiles(path)).execute(buildLog, buildEnvironment);
	}

	@NotNull
	public static SpecifyClassName classExists(final @NotNull String className)
	{
		return new SpecifyClassName(className);
	}

	public static final class SpecifyClassName
	{
		private final String className;

		private SpecifyClassName(final @NotNull String className)
		{
			this.className = className;
		}

		@NotNull
		public ClassExistsAction in(final @NotNull AbsoluteDirectory directory)
		{
			return new ClassExistsAction(className, directory);
		}
	}
}
